package com.example.rabbitmq.starter.handler;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import lombok.RequiredArgsConstructor;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 失败处理器工厂类
 * 负责根据配置的类路径动态加载和管理失败处理器实例
 */
@Component
@RequiredArgsConstructor
public class FailureHandlerFactory {

    private static final Logger logger = LoggerFactory.getLogger(FailureHandlerFactory.class);

    private final ApplicationContext applicationContext;

    // 缓存已创建的处理器实例
    private final Map<String, FailureHandler> handlerCache = new ConcurrentHashMap<>();

    /**
     * 根据类路径获取失败处理器实例
     *
     * @param handlerClassName 处理器类的完整路径
     * @return 失败处理器实例，如果获取失败则返回null
     */
    public FailureHandler getHandler(String handlerClassName) {
        if (!StringUtils.hasText(handlerClassName)) {
            logger.warn("失败处理器类路径为空，跳过失败处理");
            return null;
        }

        // 先从缓存中获取
        FailureHandler cachedHandler = handlerCache.get(handlerClassName);
        if (cachedHandler != null) {
            return cachedHandler;
        }

        try {
            // 尝试从Spring容器中获取Bean
            FailureHandler handler = getHandlerFromSpringContext(handlerClassName);
            if (handler != null) {
                handlerCache.put(handlerClassName, handler);
                logger.info("成功从Spring容器获取失败处理器: {}", handlerClassName);
                return handler;
            }

            // 如果Spring容器中没有，则通过反射创建实例
            handler = createHandlerByReflection(handlerClassName);
            if (handler != null) {
                handlerCache.put(handlerClassName, handler);
                logger.info("成功通过反射创建失败处理器: {}", handlerClassName);
                return handler;
            }

        }
        catch (Exception e) {
            logger.error("获取失败处理器时发生异常, className: {}, error: {}", handlerClassName, e.getMessage(), e);
        }

        logger.warn("无法获取失败处理器: {}", handlerClassName);
        return null;
    }

    /**
     * 从Spring容器中获取处理器Bean
     */
    private FailureHandler getHandlerFromSpringContext(String handlerClassName) {
        try {
            // 尝试通过类名获取Bean
            Class<?> handlerClass = Class.forName(handlerClassName);
            Map<String, ?> beans = applicationContext.getBeansOfType(handlerClass);

            if (!beans.isEmpty()) {
                Object handler = beans.values().iterator().next();
                if (handler instanceof FailureHandler) {
                    return (FailureHandler) handler;
                }
            }

            // 尝试通过简单类名获取Bean
            String simpleName = handlerClass.getSimpleName();
            String beanName = Character.toLowerCase(simpleName.charAt(0)) + simpleName.substring(1);

            if (applicationContext.containsBean(beanName)) {
                Object bean = applicationContext.getBean(beanName);
                if (bean instanceof FailureHandler) {
                    return (FailureHandler) bean;
                }
            }

        }
        catch (Exception e) {
            logger.debug("从Spring容器获取处理器失败: {}, 将尝试反射创建", handlerClassName);
        }

        return null;
    }

    /**
     * 通过反射创建处理器实例
     */
    private FailureHandler createHandlerByReflection(String handlerClassName) {
        try {
            Class<?> handlerClass = Class.forName(handlerClassName);

            // 检查是否实现了FailureHandler接口
            if (!FailureHandler.class.isAssignableFrom(handlerClass)) {
                logger.error("类 {} 没有实现 FailureHandler 接口", handlerClassName);
                return null;
            }

            // 创建实例
            Object instance = handlerClass.getDeclaredConstructor().newInstance();
            return (FailureHandler) instance;

        }
        catch (Exception e) {
            logger.error("通过反射创建处理器实例失败: {}, error: {}", handlerClassName, e.getMessage());
            return null;
        }
    }

    /**
     * 执行失败处理
     *
     * @param handlerClassName 处理器类路径
     * @param messageId        消息ID
     * @param messageContent   消息内容
     * @param messageType      消息类型
     * @param retryCount       重试次数
     * @param lastException    最后一次异常
     */
    public void executeFailureHandler(String handlerClassName, String messageId, String messageContent,
                                      String messageType, int retryCount, Exception lastException) {
        FailureHandler handler = getHandler(handlerClassName);
        if (handler != null) {
            try {
                logger.info("开始执行失败处理器: {}, messageId: {}", handler.getHandlerName(), messageId);
                handler.handleFailure(messageId, messageContent, messageType, retryCount, lastException);
                logger.info("失败处理器执行完成: {}, messageId: {}", handler.getHandlerName(), messageId);
            }
            catch (Exception e) {
                logger.error("执行失败处理器时发生异常: {}, messageId: {}, error: {}",
                        handler.getHandlerName(), messageId, e.getMessage(), e);
            }
        }
        else {
            logger.warn("未找到有效的失败处理器: {}, messageId: {}", handlerClassName, messageId);
        }
    }

    /**
     * 清除缓存
     */
    public void clearCache() {
        handlerCache.clear();
        logger.info("失败处理器缓存已清除");
    }

    /**
     * 获取缓存中的处理器数量
     */
    public int getCacheSize() {
        return handlerCache.size();
    }
}